/**
 * Setting.h/.cpp copied from my other project (xl / todo)
 * it'll be release later.
 */
#ifndef XL_SETTING_H
#define XL_SETTING_H
#pragma once
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <Windows.h>
#include <atldef.h>

class CSetting
{
public:
	typedef std::string    KVType; // Key / Value Type
	// interface
	class IListener {
	public:
		virtual void onSettingChange(const KVType &key, const KVType &oldValue) = 0;
	};

private:
	CSetting(void);
	~CSetting(void);

	static CSetting *m_pInstance;

protected:
	std::string                        m_settingFile;

	typedef std::map<KVType, KVType>   MapType;
	typedef std::pair<KVType, KVType>  PairType;
	typedef std::set<IListener *>      ListenerContainer;
	MapType                            m_def;
	MapType                            m_map;
	MapType                            m_changed; // to be saved

	ListenerContainer                  m_listeners;
	int                                m_listenLevel;

protected:
	void _LoadDefault();
	void _LoadSetting();
	bool _SaveSetting();
	bool _CheckDigit(const KVType &str) const;
	COLORREF _ParseColor(const KVType &strColor) const;

public:
	enum {
		TOP,
		RIGHT,
		BOTTOM,
		LEFT,
	};
	static CSetting* getInstance();

	bool save();

	bool isKeyExists(const KVType &key) const;

	KVType getValue (const KVType &key) const;
	void setValue (const KVType &key, const KVType &value);


	// helper
	COLORREF getColor(const KVType &key) const;
	void setColor(const KVType &key, COLORREF value);

	int getInt(const KVType &key) const;
	void setInt(const KVType &key, int value);

	/**
	 * the order is top, right, bottom, left, just the same as the CSS
	 */
	void getPadding(int padding[4], const KVType &key) const;
	void setPadding(const KVType &key, int padding[4]);


	// listener
	bool addListener(IListener *listener);
	bool removeListener(IListener *listener);
};

#endif
